#if defined _dprp_included
	#endinput
#endif

#define _dprp_included

#include <amxmodx>
#include <engine>

/* 

This is the header file for all DPRP functions. It also contains
some documentation on how to use it. These functions require the
main plugin (usually named dprp_core.amxx/sma) to be running, otherwise
they will fail to load.

*/

#if AMXX_VERSION_NUM < 175
	#endinput
#endif

#pragma library "dprp"

// Max number of NPCs
//#define MAX_NPCS 30

// Max accesses for jobs (1 per each letter of the alphabet)
#define JOB_ACCESSES 26

// Max items in the HUD display
#define MAX_HUD_ITEMS 10

// Max keys each door can have
#define MAX_KEYS 10

// return types
enum
{
	FAILED = 0,
	SUCCEEDED
}

enum
{
	EDEKA711 = 0,
	DINER,
	BANK
}

enum _:HUD_NUM
{
	HUD_PRIM,
	HUD_SEC
}

stock g_PoliceAccessCvar[] = "dprp_police_access"
stock g_MedicalAccessCvar[] = "dprp_medical_access"
stock g_AdminAccessCvar[] = "dprp_admin_access"

stock g_JobLiterals[JOB_ACCESSES][] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}
//stock g_JobInts[JOB_ACCESSES] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152}

#define ACCESS_A (1<<0)
#define ACCESS_B (1<<1)
#define ACCESS_C (1<<2)
#define ACCESS_D (1<<3)
#define ACCESS_E (1<<4)
#define ACCESS_F (1<<5)
#define ACCESS_G (1<<6)
#define ACCESS_H (1<<7)
#define ACCESS_I (1<<8)
#define ACCESS_J (1<<9)
#define ACCESS_K (1<<10)
#define ACCESS_L (1<<11)
#define ACCESS_M (1<<12)
#define ACCESS_N (1<<13)
#define ACCESS_O (1<<14)
#define ACCESS_P (1<<15)
#define ACCESS_Q (1<<16)
#define ACCESS_R (1<<17)
#define ACCESS_S (1<<18)
#define ACCESS_T (1<<19)
#define ACCESS_U (1<<20)
#define ACCESS_V (1<<21)
#define ACCESS_W (1<<22)
#define ACCESS_X (1<<23)
#define ACCESS_Y (1<<24)
#define ACCESS_Z (1<<25)

// Gets SQL handle
native Handle:DPRP_SqlHandle()

// Gets the DPRP version
native DPRP_Version(version[],len)

// Gets the configuration directory for DPRP files
native DPRP_GetConfigsdir(configsdir[],len)

// Self explanatory: it gets the amount of jobs currently loaded in the database.
native DPRP_GetJobsNum()

// This will get the name of a job id. As in, you input 2, and it
// will give you back "MCPD Officer" or whatever the server has 2 as.
// jobid - this is the id of the job you want to get the name of
// name[] - this is the array to store the job as a string into
// len - this is the max len of name
// This will return 0 if the job does not exist or it fails for some
// reason, and will return 1 if it succeeds.
native DPRP_GetJobName(jobid,name[],len)

// This will give you the salary of a job id, measured in $.
// jobid - this is the id of the job you want to get the salary of
native DPRP_GetJobSalary(jobid)

//
native DPRP_GetJobAccess(jobid)

// Checks if the job id is valid
// jobid - id of the job to check
native DPRP_ValidJobId(jobid)

// Gets how hungry the person is (1-100)
native DPRP_GetUserHunger(id)

// Sets how hungry the person is (1-100)
native DPRP_SetUserHunger(id,hunger)

// This will find a job ID based on a search string. Basically, if you're
// looking for the job "Hacker" and you input "Hack", it will give you the
// Job ID of "Hacker". If, however, there is another job called "Computer Hacker",
// it will insert all the results it gets into the results[] array to a max of
// maxresults. If it finds nothing, it will return 0 (FAILED), otherwise it will
// return the amount of results (i.e. if it finds 2, it will return 2)
native DPRP_FindJobId(searchstring[],results[],maxresults)

// Adds a job to the jobs database. Returns 1 on success, 0 on failure.
// name[] - name of the job, ex. "Porn Star"
// salary - the amount of money anyone with the job gets every hour
// access - access all users get who have this job, in the form of an integer
native DPRP_AddJob(name[],salary,access)

// This will register an item that can be used in game.
// This MUST be run during DPRP_RegisterItems and no other time.
// Returns FAILED (0) on failure, or an item id on success
// name[] - name of item, ex. "Lamp Shade"
// handler[] - function to call when it is used
// description - what the item is like, i.e. "Tastes like chicken."
// remove - whether or not the item should be taken away once used, if it is
// disposable
native DPRP_RegisterItem(name[],handler[],description[],remove = 0)

// Will find an item based on search string, with the same method as FindJobId.
native DPRP_FindItemId(searchstring[],results[],maxresults)

// Determines whether an item id is valid or not
native DPRP_ValidItemId(itemid)

// Will get an item's name based on an item id.
// itemid - id of the item
// name - where to store the name
// len - length of name
native DPRP_GetItemName(itemid,name[],len)

// Registers an NPC or zone. Note that this actually creates
// the NPC for you and sets it up as well. If zone is set to 1,
// the NPC will have no model, and anyone passing through the area will see
// the message explaining how to talk to the NPC. This is useful for ATMs,
// or NPCs that already exist in the map that you don't want to strip out.
// name[] - name of the NPC, ex. "Edeka Cashier"
// Float:origin[3] - where to spawn the NPC
// Float:angle - which direction it should face (0.0-180.0)
// model[] - the model the NPC should use (if not a zone)
// handler[] - function to call when a user presses "e" next to it
// zone - whether or not the NPC is a zone or human-looking figure
native DPRP_RegisterNpc(name[],Float:origin[3],Float:angle,model[],handler[],zone=0)

// returns SUCCEDED if is NPC, FAILED otherwise
native DPRP_IsNpc(entid)

// Adds a command to the list, aids in user interfacing
// command[] - command to register, i.e. "say /users"
// description[] - the description, i.e. "Shows user list"
native DPRP_AddCommand(const command[],const description[])

// Gets user item num
native DPRP_GetUserItemNum(id,itemid)

// Sets user item id to whatever value
native DPRP_SetUserItemNum(id,itemid,num)

// Gets a user's job rights
native DPRP_GetUserJobRight(id)

// Sets a user's job rights.
// NOTE: This does NOT allow them to keep their old flags - to do this,
// you should use DPRP_SetUserJobRight(id,myflags|DPRP_GetUserJobRight(id))
native DPRP_SetUserJobRight(id,flags)

// Sets their item to done so that they can start using other items again
native DPRP_ItemDone(id)

// Artificially tells the core that the user is using an item.
// To end this, use DPRP_ItemDone.
native DPRP_ItemSet(id)

// Sets the amount of money in someone's wallet
native DPRP_SetUserWallet(id,cash)

// Gets the amount of money in someone's wallet
native DPRP_GetUserWallet(id)

// Sets the amount of money in someone's bank account
native DPRP_SetUserBank(id,cash)

// Gets the amount of money in someone's bank account
native DPRP_GetUserBank(id)

// Gets a user's access (personal AND job access [but not job rights])
native DPRP_GetUserAccess(id)

// Sets a user's access.
// NOTE: This does NOT allow them to keep their old flags - to do this,
// you should use DPRP_SetUserAccess(id,myflags|DPRP_GetUserAccess(id))
native DPRP_SetUserAccess(id,access)

// Adds a line to a user's hud
// Do not use "^n" here, it will be replaced by the core anyway
// Note that this can only be used when DPRP_HudDisplay is called (not after or before)
// Channel is a channel from the "HUD_NUM" enum
native DPRP_AddHudItem(id,channel,const item[])

// Gets a user's job id
native DPRP_GetUserJobId(id)

// Sets a user's job id
native DPRP_SetUserJobId(id,jobid)

// Precaches a model
// This checks to make sure it won't go over the precache limit,
// and that the file to be precached actually exists.
native DPRP_PrecacheModel(const model[])

// Precaches a sound
// This checks to make sure it won't go over the precache limit,
// and that the file to be precached actually exists.
native DPRP_PrecacheSound(const sound[])

// Checks to be sure a property is valid. Pass either one, but if the
// property was registered with targetname, you should use targetname.
// Likewise, the same is true for ent.
native DPRP_ValidProperty(ent = 0, const targetname[] = "")

// Adds a property. DO NOT specify both targetname and entid.
// targetname[] - the target name of the door
// entid - usually used if there is no target name
// name[] - name of the property, i.e. "Hotel"
// price - how much it is selling for (0 to be not for sale)
// fakemsg[] - if it should be an extra door for another property
// note that fakemsg can either be an entid OR a targetname, the core
// will automatically detect which
native DPRP_AddProperty(const targetname[] = "",entid = 0,const name[],price = 0,const fakemsg[])

// Starts the robbing process.
// id - player that is robbing
// max_cash - after this amount of cash is attained, stop the robbing (ignored if BANK)
// cash_per_second - amount of cash recieved from the register every second (ignored if BANK)
// targetname[] - the targetname of the button to start the robbing
// type - either EDEKA711, DINER or BANK
native DPRP_Rob(id,max_cash,cash_per_second,const targetname[],type)

// Gets current rob details
// works the same way as above.
native DPRP_GetRob(id,&cash_second,&cash_max,&cash_taken,&type)

// Stops the robbing process.
// id - player to stop robbing
// reason[] - reason to stop the robbing (shown on HUD and DPRP_RobEnd forward)
// {Float,Sql,Result,_}:... - this native allows formatting of reason[]
native DPRP_EndRob(id,const reason[],{Float,Sql,Result,_}:...)

// Prints a message to a user via HUD or print_center, depending on cvars
// id - person to print to; use 0 for everyone
// const message[] - message to print
// {Float,Sql,Result,_}:... - allows formatting of message
native DPRP_ClientPrint(id,const message[],{Float,Sql,Result,_}:...)

// Forces a user to use an item.
// Note that they must possess at least 1 of the item with the specified
// itemid.
// Setting useup to 1 makes it such that it will both check if the user has the item,
// and that if it's disposable is on, it gets used up
// Setting it to 0 both ignores whether or not the user has the item, as well as
// the disposable setting
native DPRP_ForceUseItem(id,itemid,useup = 1)

// Throws an error at the core
// error - the error type (refer to amxconst.inc)
// fatal - whether or not this should shut the core down
// reason[] - reason for error
native DPRP_ThrowError(fatal,const reason[],{Float,Sql,Result,_}:...)

// called when SQL and stuff are ready
forward DPRP_Init()

// called when you can register items
forward DPRP_RegisterItems()

// called when someone buys a property
// return PLUGIN_HANDLED to stop
forward DPRP_BuyProperty(id,doorid,const targetname[])

// Called every second, when the HUD is displayed to a user.
// HUD items can be added using DPRP_AddHudItem.
forward DPRP_HudDisplay(id)

// called when a user robs a place
forward DPRP_UserRob(id,CashSecond,CashMax,Targetname,Type)

// called when a user is done robbing a place
forward DPRP_RobEnd(id,const reason[])

// called when a user's salary comes
// return PLUGIN_HANDLED to block
forward DPRP_Salary(id)

// called when the core is shutting down due to a fatal error
// cannot be blocked
// it is advised that you run any final commands here and pause("d")
forward DPRP_Error(const reason[])

// Registers a clcmd and adds it to the DPRP help database.
stock DPRP_RegisterCmd(command[],handler[],description[])
{
	DPRP_AddCommand(command,description)
	
	register_clcmd(command,handler,ADMIN_ALL,description)
}

// Converts a string, i.e. "abc" to a number (in this case, "a" = 1, 
// "b" = 2, "c" = 4, so 7 in total).
// Returns the number.
stock DPRP_AccessToInt(string[])
{
	new Access
	
	for(new Count;Count < JOB_ACCESSES;Count++)
		if(containi(string,g_JobLiterals[Count]) != -1)
			Access |= (1<<Count)
	
	return Access
}

// Reverses the process of DPRP_AccessToInt.
stock DPRP_IntToAccess(access,string[],len)
{
	copy(string,len,"")
	
	for(new Count;Count < JOB_ACCESSES;Count++)
		if(access & (1<<Count))
			add(string,len,g_JobLiterals[Count])
}

// Gets the admin access
// If id is specified as a player that is connected,
// it will return whether or not the user is an admin.
stock DPRP_AdminAccess(id = 0)
{
	new String[JOB_ACCESSES + 1]
	get_cvar_string(g_AdminAccessCvar,String,JOB_ACCESSES)
	
	new Flag = DPRP_AccessToInt(String)
	
	if(id)
		return is_user_connected(id) ? DPRP_GetUserAccess(id) & Flag : FAILED
	
	return Flag
}

// Sets the owner of a property. Do not specify both
// ent and targetname. 'owner' must be a player currently
// connected.
stock DPRP_SetPropertyOwner(ent = 0,targetname[] = "",owner)
{
	if(!is_user_connected(owner))
		return FAILED
	
	new Ownername[33],Ownerauth[36],Targetname[33]
	get_user_authid(owner,Ownerauth,35)
	get_user_name(owner,Ownername,32)
	DPRP_RealProperty(ent,targetname,Targetname,32)
	
	if(!ent)
		while((ent = find_ent_by_tname(Ent,Targetname)) != 0)
		{
			entity_set_string(Ent,EV_SZ_viewmodel,Ownerauth)
			entity_set_string(Ent,EV_SZ_weaponmodel,Ownername)
		}
	else
	{
		entity_set_string(Ent,EV_SZ_viewmodel,Ownerauth)
		entity_set_string(Ent,EV_SZ_weaponmodel,Ownername)
	}
	
	return Ent ? SUCCEEDED : FAILED
}

// Gets a property's owner. If the player is not connected, it will
// return 0. Otherwise, it returns the player's id.
stock DPRP_GetPropertyOwner(ent = 0,targetname[] = "")
{
	new Ownerauth[36],Authid[36]

	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!ent)
		return FAILED
	
	entity_get_string(ent,EV_SZ_viewmodel,Ownerauth,35)
	
	new Players[32],Playersnum,Player
	get_players(Players,Playersnum)
	
	for(new Count;Count < Playersnum;Count++)
	{
		Player = Players[Count]
		
		get_user_authid(Player,Authid,35)
		
		if(equal(Authid,Ownerauth))
			return Player
	}
	
	return FAILED
}

// Gets a property's price.
stock DPRP_GetPropertyPrice(ent = 0,targetname[] = "")
{
	if(!DPRP_ValidProperty(ent,targetname))
		return FAILED
	
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!ent)
		return FAILED
	
	return entity_get_int(ent,EV_INT_iuser1)
}

// Sets a property's price.
stock DPRP_SetPropertyPrice(ent = 0,targetname[] = "",price)
{
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent,targetname))
		return FAILED
	
	new Ent
	if(!ent)
		while((ent = find_ent_by_tname(Ent,targetname)) != 0)
			entity_set_int(Ent,EV_INT_iuser1,price)
	else	
		entity_set_int(Ent,EV_INT_iuser1,price)
		
	return SUCCEEDED
}

// Gets a property's access.
stock DPRP_GetPropertyAccess(ent = 0,targetname[] = "")
{
	if(!DPRP_ValidProperty(ent,targetname))
		return FAILED
	
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!ent)
		return FAILED
	
	return entity_get_int(ent,EV_INT_iuser3)
}

// Sets a property's access.
stock DPRP_SetPropertyAccess(ent = 0,targetname[] = "",access)
{
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent,targetname))
		return FAILED
	
	new Ent
	if(!ent)
		while((ent = find_ent_by_tname(ent,targetname)) != 0)
			entity_set_int(Ent,EV_INT_iuser3,access)
	else	
		entity_set_int(Ent,EV_INT_iuser3,access)
	
	return SUCCEEDED
}

// Checks if a player has access to a property (with keys)
stock DPRP_KeyProperty(id,ent = 0,targetname[] = "")
{
	if(!is_user_connected(id))
		return FAILED
		
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	new Authid[36],Cache[MAX_KEYS * 40]
	get_user_authid(id,Authid,35)
	
	entity_get_string(ent,EV_SZ_message,Cache,MAX_KEYS * 40 - 1)
	
	return containi(Cache,Authid) != -1 ? SUCCEEDED : FAILED
}

// Adds a user to a property's access list (keys)	
stock DPRP_KeyPropertyAdd(id,ent = 0,targetname[] = "")
{
	if(!is_user_connected(id))
		return FAILED
	
	new Authid[36],Cache[MAX_KEYS * 40],Ent,Num
	get_user_authid(id,Authid,35)
	
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	entity_get_string(ent,EV_SZ_message,Cache,MAX_KEYS * 40 - 1)
	
	new Len = strlen(Cache)
	for(new Count;Count < Len;Count++)
		if(Cache[Count] == '|')
			Num++
	
	if(Num >= MAX_KEYS)
		return FAILED
		
	format(Cache[Len],MAX_KEYS * 40 - 1 - Len,"|%s",Authid)
	
	if(!ent)
		while((Ent = find_ent_by_tname(Ent,targetname)) != 0)
			entity_set_string(Ent,EV_SZ_message,Cache)
	else
		entity_set_string(ent,EV_SZ_message,Cache)
	
	return SUCCEEDED
}

// Deletes a user from a property's access list (keys)
stock DPRP_KeyPropertyDel(id,ent = 0,targetname[] = "")
{
	if(!is_user_connected(id))
		return FAILED
	
	new Authid[36],Cache[MAX_KEYS * 40],Temp[38],Ent
	get_user_authid(id,Authid,35)
	
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	entity_get_string(Ent,EV_SZ_message,Cache,MAX_KEYS * 40 - 1)
		
	format(Temp,37,"|%s",Authid)
	new Num = replace(Cache,MAX_KEYS * 40 - 1,Temp,"")
	
	if(!ent)
		while((Ent = find_ent_by_tname(Ent,targetname)) != 0)
			entity_set_string(Ent,EV_SZ_message,Cache)
	else
		entity_set_string(ent,EV_SZ_message,Cache)
	
	return Num ? SUCCEEDED : FAILED
}

// Gets a property's name
stock DPRP_GetPropertyName(ent = 0,targetname[] = "",name[],len)
{
	if(!DPRP_ValidProperty(_,targetname))
		return FAILED
	
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	entity_get_string(ent,EV_SZ_noise,name,len)
	
	return SUCCEEDED
}

// Sets a property's name
stock DPRP_SetPropertyName(ent = 0,targetname[] = "",name[])
{
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	new Ent
	if(!ent)
		while((Ent = find_ent_by_tname(Ent,targetname)) != 0)
			entity_set_string(Ent,EV_SZ_noise,name)
	else
		entity_set_string(ent,EV_SZ_noise,name)
	
	return SUCCEEDED
}

// Gets a property's owner's name
stock DPRP_GetPropertyOwnerName(ent = 0,targetname[] = "",name[],len)
{
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	entity_get_string(ent,EV_SZ_weaponmodel,name,len)
	
	return SUCCEEDED
}

// Sets a property's owner's name
stock DPRP_SetPropertyOwnerName(ent = 0,targetname[] = "",name[])
{
	DPRP_RealProperty(ent,targetname,targetname,1)
	
	if(!DPRP_ValidProperty(ent))
		return FAILED
	
	new Ent
	if(!ent)
		while((Ent = find_ent_by_tname(Ent,targetname)) != 0)
			entity_set_string(Ent,EV_SZ_weaponmodel,name)
	else
		entity_set_string(ent,EV_SZ_weaponmodel,name)
	
	return SUCCEEDED
}

// Gets an NPC's name
stock DPRP_GetNpcName(npc,string[],len)
{
	if(!is_valid_ent(npc) || !DPRP_IsNpc(npc))
		return FAILED
	
	entity_get_string(npc,EV_SZ_noise1,string,len)
	
	return SUCCEEDED
}

// Gets the distance between a player and an NPC
stock DPRP_NpcDistance(id,npc)
{
	if(!is_user_connected(id))
		return FAILED
	
	new Float:PlOrigin[3],Float:NpcOrigin[3]
	entity_get_vector(id,EV_VEC_origin,PlOrigin)
	entity_get_vector(npc,EV_VEC_origin,NpcOrigin)
	
	if(get_distance_f(PlOrigin,NpcOrigin) > 100.0)
	{
		client_print(id,print_chat,"[DPRP] You are too far from this NPC.")
		return FAILED
	}
	
	return SUCCEEDED
}

// Checks if a player is a cop
stock DPRP_IsCop(id)
{
	new UserAccess = DPRP_GetUserAccess(id),Temp[JOB_ACCESSES + 1]
	get_cvar_string(g_PoliceAccessCvar,Temp,JOB_ACCESSES)
	
	new JobAccess = DPRP_AccessToInt(Temp)
	
	if(UserAccess & JobAccess)
		return SUCCEEDED
		
	return FAILED
}

// Checks if a player is medical (i.e. doctor)
stock DPRP_IsMed(id)
{
	new UserAccess = DPRP_GetUserAccess(id),Temp[JOB_ACCESSES + 1]
	get_cvar_string(g_MedicalAccessCvar,Temp,JOB_ACCESSES)
	
	new JobAccess = DPRP_AccessToInt(Temp)
	
	if(UserAccess & JobAccess)
		return SUCCEEDED
		
	return FAILED
}

// cmd_access adapted to DPRP access system
stock DPRP_CmdAccess(id,cid,num)
{
  new StrAccess[JOB_ACCESSES + 1]
  get_cvar_string("dprp_admin_access",StrAccess,JOB_ACCESSES)
	
  new Access = DPRP_AccessToInt(StrAccess)
	
  new has_access = 0
  if ( id==(is_dedicated_server()?0:1) ) {
    has_access = 1
  /*} else if ( level==ADMIN_ADMIN ) {
    if ( is_user_admin(id) )
      has_access = 1*/
  } else if ( DPRP_GetUserAccess(id) & Access ) {
    has_access = 1
  } else if (Access == 0) {
	has_access = 1
  }

  if ( has_access==0 ) {
    console_print(id,"%L",id,"NO_ACC_COM")
    return 0
  }
  if (read_argc() < num) {
    new hcmd[32], hinfo[128], hflag
    get_concmd(cid,hcmd,31,hflag,hinfo,127,0)
    console_print(id,"%L:  %s %s",id,"USAGE",hcmd,hinfo)
    return 0
  }
  return 1
}

// Checks if a user has job rights to a job id
stock DPRP_JobAccess(id,jobid)
{
	if(!DPRP_ValidJobId(jobid) || !is_user_connected(id))
		return FAILED
	
	return DPRP_GetUserJobRight(id) & DPRP_GetJobAccess(jobid)
}

// Gets a property's real targetname or ent id.
// If it has fakemsg set, this will find the real property.
stock DPRP_RealProperty(&ent,targetname[] = "",string[],len)
{
	if(!ent)
		ent = find_ent_by_tname(-1,targetname)
	
	if(!ent || !is_valid_ent(ent) || !entity_get_int(ent,EV_INT_bInDuck))
		return FAILED
	
	new FakeMsg[33]
	entity_get_string(ent,EV_SZ_globalname,FakeMsg,32)
	
	if(!FakeMsg[0])
	{
		copy(string,len,targetname)
		return SUCCEEDED
	}
	
	new Temp
	
	if(is_str_num(FakeMsg) && is_valid_ent((Temp = str_to_num(FakeMsg))))
		ent = Temp
	else if(is_valid_ent((Temp = find_ent_by_tname(-1,FakeMsg))))
		ent = Temp
	
	entity_get_string(ent,EV_SZ_targetname,string,len)
	
	return SUCCEEDED
}	

// Thanks to xeroblood
stock ExplodeString( p_szOutput[][], p_iMax, p_szInput[], p_iSize, p_szDelimiter )
{
	new iIdx = 0, l = strlen(p_szInput)
	new iLen = (1 + copyc( p_szOutput[iIdx], p_iSize, p_szInput, p_szDelimiter ))
	while( (iLen < l) && (++iIdx < p_iMax) )
		iLen += (1 + copyc( p_szOutput[iIdx], p_iSize, p_szInput[iLen], p_szDelimiter ))
	return iIdx
}  
